package com.zwcl.glass.goods.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zwcl.common.core.domain.entity.ApiResult;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.glass.goods.dto.UserSpuDto;
import com.zwcl.glass.goods.entity.GoodsSpu;
import com.zwcl.glass.goods.enums.GlassCateEnum;
import com.zwcl.glass.goods.enums.GlassTagsScoreEnum;
import com.zwcl.glass.goods.service.CategoriesService;
import com.zwcl.glass.goods.service.GoodsCommonService;
import com.zwcl.glass.goods.service.GoodsRecommendService;
import com.zwcl.glass.tools.api.dto.UserTagsDto;
import com.zwcl.glass.tools.api.entity.UserReport;
import com.zwcl.glass.tools.api.enums.TestCodeEnum;
import com.zwcl.glass.tools.api.feign.UserReportFacadeClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GoodsRecommendServiceImpl implements GoodsRecommendService {
    @Autowired
    private UserReportFacadeClient userReportFacadeClient;

    @Autowired
    private GoodsCommonService goodsCommonService;

    /**
     * TODO:可以将用户的结果缓存10天
     * 当用户有重新测试时，删除缓存
     * @param userTags
     * @return
     */
    @Override
    public List<GoodsSpu> getSpusByUserTag(String userTags) {
        //获取镜片的标签
        //String glassTags=userTags.get(paperCode);
        if(StringUtils.isNotBlank(userTags)){                      //有用户标签
            log.info("用户的镜片标签：{}",userTags);
            String[] userTagClassArr= userTags.split(";");
            //拆开用户的所有的标签
            Map<String,String> userTagMap =new HashMap<>();
            for (String userTagClass : userTagClassArr){
                String[] userTagArr = userTagClass.trim().split(":");
                userTagMap.put(userTagArr[0],userTagArr[1]);
            }
            //查询所有的镜片，目前分类是写死
            List<GoodsSpu> goodsSpuList = goodsCommonService.getSpuByCateCode(GlassCateEnum.GLASS.getValue());
            //先根据折射率获取镜片
            String refractionTag= userTagMap.get(GlassTagsScoreEnum.REFRACTION.getValue());
            goodsSpuList = filterSpusByRefraction(goodsSpuList,refractionTag);
            //移除折射率标签
            userTagMap.remove(GlassTagsScoreEnum.REFRACTION.getValue());
            //对镜片根据其他的标签进行打分排序
            if(userTagMap.size()>0) {
                goodsSpuList.forEach(item -> {
                    Integer score = computeSpuScore(item.getTags(), userTagMap);
                    item.setScore(score);
                });
                //对商品进行排序
                Collections.sort(goodsSpuList, new Comparator<GoodsSpu>() {
                    @Override
                    public int compare(GoodsSpu A1, GoodsSpu A2) {
                        return A2.getScore().compareTo(A1.getScore());
                    }
                });
            }
            return goodsSpuList;
        }
        return null;
    }

    /**
     * 先根据折射率过滤镜片
     * TODO: 折射率的中的镜片，可能是有序的
     * @param goodsSpuList
     * @param refractionTag
     * @return
     */
    private List<GoodsSpu> filterSpusByRefraction(List<GoodsSpu> goodsSpuList,String refractionTag ){
        if(StringUtils.isNotBlank(refractionTag)) {
            //可能适合多个折射率
            String[] refractionArr = refractionTag.split(",");
            //根据折射率查询spu 或者sku
            goodsSpuList = goodsSpuList.stream().filter(x->{
                Boolean matchflag =false;
                for(String refraction : refractionArr){
                    if(x.getTags().contains("|"+refraction+"|")) {
                        matchflag = true;
                        break;
                    }
                }
                return matchflag;
            }).collect(Collectors.toList());
        }
        return goodsSpuList;
    }

    @Override
    public UserReport getUserReportTags(Integer userId) {
        UserTagsDto userTagsDto=new UserTagsDto();
        //现在只查镜片
        userTagsDto.setPaperCodes(Arrays.asList(TestCodeEnum.JING_PIAN.getCode()));
        userTagsDto.setUserId(userId);
        ApiResult<UserReport> userReportResult= userReportFacadeClient.getUserReportTags(userTagsDto);
        log.info("用户画像：{}",userReportResult.toString());
        if(userReportResult.getCode()!=200){
            log.error("调用glass-tools服务的getUserReportTags接口失败，原因：{}",userReportResult.getMessage());
            throw new BusinessException("调用glass-tools服务的getUserReportTags接口失败");
        }
        UserReport userReport = userReportResult.getData();
        return userReport;
    }

    /**
     * 计算商品和用户的相关度打分
     * @param spuTags
     * @param userTags
     * @return
     */
    @Override
    public Integer computeSpuScore(String spuTags, Map<String, String> userTags) {
        Integer totalScore = 0;
        for(Map.Entry<String,String> item : userTags.entrySet()){
            if(spuTags.contains("|"+item.getValue()+"|")){
                totalScore += GlassTagsScoreEnum.of(item.getKey()).getWeight();
            }
        }
        return totalScore;
    }
}
